package p.ithorns.framework.feign.enhance;

import com.google.common.collect.Sets;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.*;

/**
 * FeignBeanPostProcessor
 *
 * 测试发现，注册RequestMapping的方式不可用，还不如直接继承@Controller
 *
 * @author HtL
 * @date 2024/8/30 16:28
 * @since 1.0.0
 */
public class FeignBeanPostProcessor implements BeanPostProcessor {

//    private final RequestMappingHandlerMapping requestMapping;
//    public FeignBeanPostProcessor(RequestMappingHandlerMapping requestMapping) {
//        this.requestMapping = requestMapping;
//    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (hasFeignSvcAnnotation(bean)) {
            // 如果是通过接口实现的，使用JDK代理, 如果是通过类实现的，需要使用CGLIB代理， 否则没有必要使用代理
            return createJdkProxy(bean.getClass(), bean);
            // registerMapping(bean);
        }
        return bean;
    }

    private boolean isFeinController(Object bean) {
        return FeignController.class.isAssignableFrom(bean.getClass());
    }

    private Object createJdkProxy(Class<?> type, Object instance) {
        Set<Class<?>> classes = Sets.newLinkedHashSet(Arrays.asList(type.getInterfaces()));
        classes.add(FeignController.class);
        Class<?>[] interfaces = classes.toArray(new Class<?>[0]);
        return Proxy.newProxyInstance(
                type.getClassLoader(),
                interfaces,
                new FeignSvcJdkProxy(instance)
        );
    }


    private boolean hasFeignSvcAnnotation(Object bean) {
        Class<?> aClass = bean.getClass();
        Class<?>[] interfaces = aClass.getInterfaces();
        for (Class<?> anInterface : interfaces) {
            if (anInterface.isAnnotationPresent(FeignSvc.class)) {
                return true;
            }
        }
        return false;
    }


    /**
     * 注册RequestMapping的方式不可用
     */
    private void registerMapping(Object bean) {
        // 遍历Bean的所有方法
        Class<?> aClass = bean.getClass();
        for (Method method : aClass.getMethods()) {
            // 检查方法是否已经有@RequestMapping注解
            if (!method.isAnnotationPresent(RequestMapping.class)) {
                // 动态添加@RequestMapping注解，这里只是一个示例，可以根据需要配置路径等
                // 例如，我们可以将所有方法映射到"/hello/"路径下
                RequestMapping rm = AnnotationUtils.findAnnotation(method, RequestMapping.class);
                // 最终执行注册动态控制器方法
                RequestMappingInfo requestMappingInfo = RequestMappingInfo
                        .paths(rm.value())
                        .methods(rm.method())
                        .build();
                // requestMapping.registerMapping(requestMappingInfo, bean, method);
            }
        }
    }
}